"""
Resolution command for CodeMCP CLI.

Performs cross-file dependency resolution, symbol linkage,
and inter-language bridge detection.
"""

import argparse
import asyncio
from typing import List, Dict, Any, Optional, Set
from pathlib import Path
import json

from ...core.cross_file_resolver import CrossFileResolver, ResolutionConfig, DependencyGraph
from ...core.project_scanner import ProjectScanner, ProjectScanConfig
from ...core.error_handler import CodeMCPError, log_info, log_debug
from ..base_command import CLICommand


class ResolveCommand(CLICommand):
    """Command for resolving cross-file dependencies and symbol linkage."""
    
    def add_parser(self, subparsers) -> argparse.ArgumentParser:
        """Add resolve command parser."""
        parser = subparsers.add_parser(
            'resolve',
            help='Resolve cross-file dependencies and symbol linkage',
            description='Analyze and resolve dependencies, imports, includes, and symbol references',
            formatter_class=argparse.RawDescriptionHelpFormatter,
            epilog="""
Examples:
  codemcp resolve                           # Resolve all dependencies in current directory
  codemcp resolve --path /path/to/project   # Resolve dependencies in specific project
  codemcp resolve --file main.py            # Resolve dependencies for specific file
  codemcp resolve --symbol function_name    # Resolve specific symbol across project
  codemcp resolve --show-circular           # Show circular dependencies
  codemcp resolve --language python         # Only resolve Python dependencies
  codemcp resolve --depth 5                 # Limit resolution depth
  codemcp resolve --export-graph deps.json  # Export dependency graph
  codemcp resolve --visualize               # Create dependency visualization
            """.strip()
        )
        
        # Target options
        parser.add_argument(
            '--path', '-p',
            type=str,
            default='.',
            help='Project path to analyze (default: current directory)'
        )
        parser.add_argument(
            '--file', '-f',
            type=str,
            help='Specific file to resolve dependencies for'
        )
        parser.add_argument(
            '--symbol', '-s',
            type=str,
            help='Specific symbol to resolve across project'
        )
        parser.add_argument(
            '--module', '-m',
            type=str,
            help='Specific module to resolve dependencies for'
        )
        
        # Language filtering
        parser.add_argument(
            '--language', '-l',
            choices=['python', 'cpp', 'typescript', 'fortran', 'all'],
            default='all',
            help='Language to focus on (default: all)'
        )
        parser.add_argument(
            '--languages',
            nargs='+',
            choices=['python', 'cpp', 'typescript', 'fortran'],
            help='Multiple languages to include'
        )
        
        # Resolution options
        parser.add_argument(
            '--depth', '-d',
            type=int,
            default=10,
            help='Maximum resolution depth (default: 10)'
        )
        parser.add_argument(
            '--include-external',
            action='store_true',
            help='Include external/library dependencies'
        )
        parser.add_argument(
            '--include-transitive',
            action='store_true',
            help='Include transitive dependencies'
        )
        parser.add_argument(
            '--resolve-symbols',
            action='store_true',
            help='Perform detailed symbol resolution'
        )
        parser.add_argument(
            '--cross-language',
            action='store_true',
            help='Enable cross-language dependency resolution'
        )
        
        # Analysis options
        parser.add_argument(
            '--show-circular',
            action='store_true',
            help='Show circular dependencies'
        )
        parser.add_argument(
            '--show-missing',
            action='store_true',
            help='Show missing/unresolved dependencies'
        )
        parser.add_argument(
            '--show-unused',
            action='store_true',
            help='Show unused imports/includes'
        )
        parser.add_argument(
            '--analyze-complexity',
            action='store_true',
            help='Analyze dependency complexity metrics'
        )
        parser.add_argument(
            '--find-entry-points',
            action='store_true',
            help='Find entry points in dependency graph'
        )
        
        # Output options
        parser.add_argument(
            '--show-details',
            action='store_true',
            help='Show detailed dependency information'
        )
        parser.add_argument(
            '--show-paths',
            action='store_true',
            help='Show full file paths in output'
        )
        parser.add_argument(
            '--group-by',
            choices=['file', 'language', 'type', 'level'],
            default='file',
            help='Group results by file, language, type, or level (default: file)'
        )
        parser.add_argument(
            '--format',
            choices=['tree', 'list', 'graph', 'table'],
            default='tree',
            help='Output format (default: tree)'
        )
        
        # Export options
        parser.add_argument(
            '--export-graph',
            type=str,
            help='Export dependency graph to JSON file'
        )
        parser.add_argument(
            '--export-dot',
            type=str,
            help='Export dependency graph to DOT format'
        )
        parser.add_argument(
            '--export-csv',
            type=str,
            help='Export dependency list to CSV file'
        )
        parser.add_argument(
            '--visualize',
            action='store_true',
            help='Create HTML visualization of dependency graph'
        )
        
        # Resolution configuration
        parser.add_argument(
            '--resolve-method',
            choices=['static', 'dynamic', 'hybrid'],
            default='hybrid',
            help='Resolution method (default: hybrid)'
        )
        parser.add_argument(
            '--cache-results',
            action='store_true',
            default=True,
            help='Cache resolution results for performance'
        )
        
        return parser
    
    async def execute(self, args: argparse.Namespace) -> int:
        """Execute the resolve command."""
        try:
            self.printer.print_info("🔗 Starting dependency resolution...")
            
            # Validate inputs
            project_path = Path(args.path).resolve()
            if not project_path.exists():
                raise CodeMCPError(f"Project path does not exist: {project_path}")
            
            if args.file:
                file_path = Path(args.file).resolve()
                if not file_path.exists():
                    raise CodeMCPError(f"File does not exist: {file_path}")
            
            # Setup configuration
            resolution_config = self._create_resolution_config(args)
            scan_config = self._create_scan_config(args)
            
            # Initialize components
            resolver = CrossFileResolver(resolution_config)
            project_scanner = ProjectScanner(scan_config)
            
            # Perform resolution
            results = await self._perform_resolution(
                resolver, project_scanner, project_path, args
            )
            
            # Process and display results
            await self._display_results(results, args)
            
            # Export results if requested
            if args.export_graph:
                await self._export_graph(results, args.export_graph)
            
            if args.export_dot:
                await self._export_dot(results, args.export_dot)
            
            if args.export_csv:
                await self._export_csv(results, args.export_csv)
            
            if args.visualize:
                await self._create_visualization(results, args)
            
            self.printer.print_success("✅ Resolution completed successfully!")
            return 0
            
        except Exception as e:
            self.printer.print_error(f"Resolution failed: {e}")
            log_debug(f"Resolution error details: {e}")
            return 1
    
    def _create_resolution_config(self, args: argparse.Namespace) -> ResolutionConfig:
        """Create resolution configuration."""
        # Determine languages to include
        languages = []
        if args.language != 'all':
            languages = [args.language]
        elif args.languages:
            languages = args.languages
        else:
            languages = ['python', 'cpp', 'typescript', 'fortran']
        
        return ResolutionConfig(
            max_depth=args.depth,
            include_external_deps=args.include_external,
            include_transitive_deps=args.include_transitive,
            resolve_symbols=args.resolve_symbols,
            cross_language_resolution=args.cross_language,
            resolution_method=args.resolve_method,
            cache_results=args.cache_results,
            languages=languages,
            analyze_circular_deps=args.show_circular,
            find_missing_deps=args.show_missing,
            find_unused_imports=args.show_unused
        )
    
    def _create_scan_config(self, args: argparse.Namespace) -> ProjectScanConfig:
        """Create project scan configuration."""
        return ProjectScanConfig(
            deep_scan=True,
            include_dependencies=args.include_external,
            ignore_build_dirs=True,
            ignore_cache_dirs=True,
            max_depth=args.depth + 5  # Allow deeper scanning than resolution
        )
    
    async def _perform_resolution(
        self,
        resolver: CrossFileResolver,
        project_scanner: ProjectScanner,
        project_path: Path,
        args: argparse.Namespace
    ) -> Dict[str, Any]:
        """Perform the actual resolution process."""
        results = {
            'project_path': str(project_path),
            'dependency_graph': {},
            'resolution_summary': {},
            'project_info': {},
            'analysis_results': {},
            'statistics': {}
        }
        
        with self.progress.spinner("Scanning project structure..."):
            # Scan project structure
            project_info = project_scanner.scan_project(project_path)
            results['project_info'] = project_info
        
        with self.progress.spinner("Building dependency graph..."):
            if args.file:
                # Resolve dependencies for specific file
                file_path = Path(args.file).resolve()
                dependency_graph = resolver.resolve_file_dependencies(
                    str(file_path), project_path
                )
            elif args.symbol:
                # Resolve specific symbol
                symbol_resolution = resolver.resolve_symbol(
                    args.symbol, project_path
                )
                results['symbol_resolution'] = symbol_resolution
                dependency_graph = symbol_resolution.get('dependency_graph', {})
            elif args.module:
                # Resolve specific module
                module_resolution = resolver.resolve_module_dependencies(
                    args.module, project_path
                )
                dependency_graph = module_resolution
            else:
                # Resolve entire project
                dependency_graph = resolver.resolve_project_dependencies(project_path)
            
            results['dependency_graph'] = dependency_graph
        
        # Perform additional analysis
        with self.progress.spinner("Analyzing dependencies..."):
            analysis_results = {}
            
            # Find circular dependencies
            if args.show_circular:
                circular_deps = resolver.find_circular_dependencies(dependency_graph)
                analysis_results['circular_dependencies'] = circular_deps
            
            # Find missing dependencies
            if args.show_missing:
                missing_deps = resolver.find_missing_dependencies(dependency_graph)
                analysis_results['missing_dependencies'] = missing_deps
            
            # Find unused imports
            if args.show_unused:
                unused_imports = resolver.find_unused_imports(dependency_graph)
                analysis_results['unused_imports'] = unused_imports
            
            # Analyze complexity
            if args.analyze_complexity:
                complexity_metrics = resolver.analyze_dependency_complexity(dependency_graph)
                analysis_results['complexity_metrics'] = complexity_metrics
            
            # Find entry points
            if args.find_entry_points:
                entry_points = resolver.find_dependency_entry_points(dependency_graph)
                analysis_results['entry_points'] = entry_points
            
            results['analysis_results'] = analysis_results
        
        # Generate statistics
        results['statistics'] = self._generate_resolution_statistics(
            dependency_graph, analysis_results, project_info
        )
        
        # Create resolution summary
        results['resolution_summary'] = self._create_resolution_summary(
            dependency_graph, analysis_results, args
        )
        
        return results
    
    def _generate_resolution_statistics(
        self,
        dependency_graph: Dict[str, Any],
        analysis_results: Dict[str, Any],
        project_info: Dict[str, Any]
    ) -> Dict[str, Any]:
        """Generate resolution statistics."""
        stats = {
            'total_files': len(dependency_graph.get('nodes', {})),
            'total_dependencies': 0,
            'by_language': {},
            'by_type': {},
            'depth_distribution': {},
            'circular_dependencies': len(analysis_results.get('circular_dependencies', [])),
            'missing_dependencies': len(analysis_results.get('missing_dependencies', [])),
            'unused_imports': len(analysis_results.get('unused_imports', [])),
            'resolution_coverage': 0.0
        }
        
        # Count dependencies and analyze distribution
        edges = dependency_graph.get('edges', [])
        stats['total_dependencies'] = len(edges)
        
        # Calculate statistics from edges
        for edge in edges:
            # Count by dependency type
            dep_type = edge.get('type', 'unknown')
            stats['by_type'][dep_type] = stats['by_type'].get(dep_type, 0) + 1
            
            # Count by language
            source_lang = edge.get('source_language', 'unknown')
            target_lang = edge.get('target_language', 'unknown')
            
            stats['by_language'][source_lang] = stats['by_language'].get(source_lang, 0) + 1
            if source_lang != target_lang:
                stats['by_language'][target_lang] = stats['by_language'].get(target_lang, 0) + 1
        
        # Calculate resolution coverage
        total_possible_deps = dependency_graph.get('metadata', {}).get('total_imports', 0)
        if total_possible_deps > 0:
            resolved_deps = stats['total_dependencies'] - stats['missing_dependencies']
            stats['resolution_coverage'] = (resolved_deps / total_possible_deps) * 100
        
        return stats
    
    def _create_resolution_summary(
        self,
        dependency_graph: Dict[str, Any],
        analysis_results: Dict[str, Any],
        args: argparse.Namespace
    ) -> Dict[str, Any]:
        """Create a summary of resolution results."""
        summary = {
            'resolution_method': args.resolve_method,
            'max_depth': args.depth,
            'languages_analyzed': args.languages or ['all'],
            'issues_found': {},
            'recommendations': []
        }
        
        # Identify issues
        if analysis_results.get('circular_dependencies'):
            summary['issues_found']['circular_dependencies'] = len(
                analysis_results['circular_dependencies']
            )
            summary['recommendations'].append(
                "Review circular dependencies to improve code organization"
            )
        
        if analysis_results.get('missing_dependencies'):
            summary['issues_found']['missing_dependencies'] = len(
                analysis_results['missing_dependencies']
            )
            summary['recommendations'].append(
                "Install or resolve missing dependencies"
            )
        
        if analysis_results.get('unused_imports'):
            summary['issues_found']['unused_imports'] = len(
                analysis_results['unused_imports']
            )
            summary['recommendations'].append(
                "Remove unused imports to clean up code"
            )
        
        # Add performance recommendations
        complexity_metrics = analysis_results.get('complexity_metrics', {})
        if complexity_metrics.get('high_complexity_files'):
            summary['recommendations'].append(
                "Consider refactoring high-complexity dependency structures"
            )
        
        return summary
    
    async def _display_results(self, results: Dict[str, Any], args: argparse.Namespace):
        """Display resolution results."""
        dependency_graph = results['dependency_graph']
        analysis_results = results['analysis_results']
        statistics = results['statistics']
        summary = results['resolution_summary']
        
        # Display project information
        self.printer.print_header("📁 Project Information")
        self.formatter.print_key_value_pairs({
            "Project Path": results['project_path'],
            "Resolution Method": summary['resolution_method'],
            "Max Depth": summary['max_depth'],
            "Languages": ', '.join(summary['languages_analyzed'])
        })
        
        # Display statistics
        self.printer.print_header("📊 Resolution Statistics")
        self.formatter.print_key_value_pairs({
            "Total Files": statistics['total_files'],
            "Total Dependencies": statistics['total_dependencies'],
            "Resolution Coverage": f"{statistics['resolution_coverage']:.1f}%"
        })
        
        # Show issues if any
        issues_found = summary['issues_found']
        if issues_found:
            self.printer.print_header("⚠️  Issues Found")
            for issue_type, count in issues_found.items():
                self.printer.print_warning(f"{issue_type.replace('_', ' ').title()}: {count}")
        
        # Display dependency type distribution
        if statistics['by_type']:
            self.printer.print_subheader("Dependency Types:")
            for dep_type, count in statistics['by_type'].items():
                self.printer.print_info(f"  {dep_type}: {count}")
        
        # Display dependencies based on format
        if args.format == 'tree':
            self._display_dependency_tree(dependency_graph, args)
        elif args.format == 'list':
            self._display_dependency_list(dependency_graph, args)
        elif args.format == 'graph':
            self._display_dependency_graph_summary(dependency_graph, args)
        elif args.format == 'table':
            self._display_dependency_table(dependency_graph, args)
        
        # Display analysis results
        await self._display_analysis_results(analysis_results, args)
        
        # Display recommendations
        if summary['recommendations']:
            self.printer.print_header("💡 Recommendations")
            for i, recommendation in enumerate(summary['recommendations'], 1):
                self.printer.print_info(f"{i}. {recommendation}")
    
    def _display_dependency_tree(self, dependency_graph: Dict[str, Any], args: argparse.Namespace):
        """Display dependencies as a tree structure."""
        self.printer.print_header("🌳 Dependency Tree")
        
        nodes = dependency_graph.get('nodes', {})
        edges = dependency_graph.get('edges', [])
        
        # Build adjacency list
        adj_list = {}
        for edge in edges:
            source = edge['source']
            target = edge['target']
            if source not in adj_list:
                adj_list[source] = []
            adj_list[source].append((target, edge))
        
        # Find root nodes (nodes with no incoming edges)
        all_targets = set(edge['target'] for edge in edges)
        root_nodes = set(nodes.keys()) - all_targets
        
        # Display tree for each root
        for root in sorted(root_nodes):
            self._display_tree_node(root, adj_list, nodes, args, visited=set())
    
    def _display_tree_node(
        self, 
        node: str, 
        adj_list: Dict[str, List], 
        nodes: Dict[str, Any], 
        args: argparse.Namespace,
        visited: Set[str] = None,
        depth: int = 0,
        is_last: bool = True
    ):
        """Display a single tree node with its dependencies."""
        if visited is None:
            visited = set()
        
        if node in visited:
            # Circular dependency
            indent = "  " * depth
            prefix = "└── " if is_last else "├── "
            self.printer.print_warning(f"{indent}{prefix}{node} (circular)")
            return
        
        visited.add(node)
        
        # Display current node
        indent = "  " * depth
        prefix = "└── " if is_last else "├── "
        
        node_info = nodes.get(node, {})
        display_name = Path(node).name if not args.show_paths else node
        language = node_info.get('language', '')
        
        if language:
            display_text = f"{display_name} ({language})"
        else:
            display_text = display_name
        
        self.printer.print_info(f"{indent}{prefix}{display_text}")
        
        # Display dependencies
        dependencies = adj_list.get(node, [])
        for i, (dep_node, edge) in enumerate(dependencies):
            is_last_dep = i == len(dependencies) - 1
            self._display_tree_node(
                dep_node, adj_list, nodes, args, 
                visited.copy(), depth + 1, is_last_dep
            )
    
    def _display_dependency_list(self, dependency_graph: Dict[str, Any], args: argparse.Namespace):
        """Display dependencies as a flat list."""
        self.printer.print_header("📝 Dependency List")
        
        edges = dependency_graph.get('edges', [])
        nodes = dependency_graph.get('nodes', {})
        
        # Group by source file if requested
        if args.group_by == 'file':
            file_deps = {}
            for edge in edges:
                source = edge['source']
                if source not in file_deps:
                    file_deps[source] = []
                file_deps[source].append(edge)
            
            for source_file, deps in file_deps.items():
                display_name = Path(source_file).name if not args.show_paths else source_file
                self.printer.print_subheader(f"📄 {display_name}")
                
                for edge in deps:
                    target = edge['target']
                    dep_type = edge.get('type', 'unknown')
                    target_display = Path(target).name if not args.show_paths else target
                    
                    self.printer.print_info(f"  └── {target_display} ({dep_type})")
        else:
            # Simple list
            for i, edge in enumerate(edges, 1):
                source = edge['source']
                target = edge['target']
                dep_type = edge.get('type', 'unknown')
                
                source_display = Path(source).name if not args.show_paths else source
                target_display = Path(target).name if not args.show_paths else target
                
                self.printer.print_info(f"{i}. {source_display} → {target_display} ({dep_type})")
    
    def _display_dependency_graph_summary(self, dependency_graph: Dict[str, Any], args: argparse.Namespace):
        """Display a summary of the dependency graph."""
        self.printer.print_header("📈 Dependency Graph Summary")
        
        nodes = dependency_graph.get('nodes', {})
        edges = dependency_graph.get('edges', [])
        
        # Calculate graph metrics
        num_nodes = len(nodes)
        num_edges = len(edges)
        
        # Calculate in-degree and out-degree
        in_degree = {}
        out_degree = {}
        
        for edge in edges:
            source = edge['source']
            target = edge['target']
            
            out_degree[source] = out_degree.get(source, 0) + 1
            in_degree[target] = in_degree.get(target, 0) + 1
        
        # Find highly connected nodes
        max_out_degree = max(out_degree.values()) if out_degree else 0
        max_in_degree = max(in_degree.values()) if in_degree else 0
        
        self.formatter.print_key_value_pairs({
            "Nodes": num_nodes,
            "Edges": num_edges,
            "Max Out-degree": max_out_degree,
            "Max In-degree": max_in_degree,
            "Density": f"{(num_edges / (num_nodes * (num_nodes - 1))) * 100:.2f}%" if num_nodes > 1 else "0%"
        })
        
        # Show most connected files
        if out_degree:
            self.printer.print_subheader("Most Dependencies (outgoing):")
            sorted_out = sorted(out_degree.items(), key=lambda x: x[1], reverse=True)[:5]
            for file_path, degree in sorted_out:
                display_name = Path(file_path).name if not args.show_paths else file_path
                self.printer.print_info(f"  {display_name}: {degree}")
        
        if in_degree:
            self.printer.print_subheader("Most Dependents (incoming):")
            sorted_in = sorted(in_degree.items(), key=lambda x: x[1], reverse=True)[:5]
            for file_path, degree in sorted_in:
                display_name = Path(file_path).name if not args.show_paths else file_path
                self.printer.print_info(f"  {display_name}: {degree}")
    
    def _display_dependency_table(self, dependency_graph: Dict[str, Any], args: argparse.Namespace):
        """Display dependencies in table format."""
        self.printer.print_header("📊 Dependency Table")
        
        edges = dependency_graph.get('edges', [])
        
        # Prepare table data
        headers = ["Source", "Target", "Type", "Language"]
        rows = []
        
        for edge in edges:
            source = edge['source']
            target = edge['target']
            dep_type = edge.get('type', 'unknown')
            language = edge.get('source_language', 'unknown')
            
            source_display = Path(source).name if not args.show_paths else source
            target_display = Path(target).name if not args.show_paths else target
            
            rows.append([source_display, target_display, dep_type, language])
        
        # Display table (simplified version)
        self.printer.print_info(f"{'Source':<20} {'Target':<20} {'Type':<15} {'Language':<10}")
        self.printer.print_info("-" * 70)
        
        for row in rows[:50]:  # Limit to first 50 rows
            self.printer.print_info(f"{row[0]:<20} {row[1]:<20} {row[2]:<15} {row[3]:<10}")
        
        if len(rows) > 50:
            self.printer.print_info(f"... and {len(rows) - 50} more dependencies")
    
    async def _display_analysis_results(self, analysis_results: Dict[str, Any], args: argparse.Namespace):
        """Display additional analysis results."""
        
        # Show circular dependencies
        if args.show_circular and 'circular_dependencies' in analysis_results:
            circular_deps = analysis_results['circular_dependencies']
            if circular_deps:
                self.printer.print_header("🔄 Circular Dependencies")
                for i, cycle in enumerate(circular_deps, 1):
                    cycle_str = " → ".join(Path(f).name for f in cycle)
                    self.printer.print_warning(f"{i}. {cycle_str}")
        
        # Show missing dependencies
        if args.show_missing and 'missing_dependencies' in analysis_results:
            missing_deps = analysis_results['missing_dependencies']
            if missing_deps:
                self.printer.print_header("❌ Missing Dependencies")
                for i, missing in enumerate(missing_deps, 1):
                    source = missing.get('source', 'unknown')
                    target = missing.get('target', 'unknown')
                    source_display = Path(source).name if not args.show_paths else source
                    self.printer.print_error(f"{i}. {source_display} → {target} (not found)")
        
        # Show unused imports
        if args.show_unused and 'unused_imports' in analysis_results:
            unused_imports = analysis_results['unused_imports']
            if unused_imports:
                self.printer.print_header("🗑️  Unused Imports")
                for i, unused in enumerate(unused_imports, 1):
                    file_path = unused.get('file', 'unknown')
                    import_name = unused.get('import', 'unknown')
                    file_display = Path(file_path).name if not args.show_paths else file_path
                    self.printer.print_warning(f"{i}. {file_display}: {import_name}")
        
        # Show entry points
        if args.find_entry_points and 'entry_points' in analysis_results:
            entry_points = analysis_results['entry_points']
            if entry_points:
                self.printer.print_header("🎯 Entry Points")
                for i, entry_point in enumerate(entry_points, 1):
                    file_path = entry_point.get('file', 'unknown')
                    function_name = entry_point.get('function', 'unknown')
                    file_display = Path(file_path).name if not args.show_paths else file_path
                    self.printer.print_info(f"{i}. {file_display}: {function_name}")
    
    async def _export_graph(self, results: Dict[str, Any], output_file: str):
        """Export dependency graph to JSON file."""
        try:
            output_path = Path(output_file)
            dependency_graph = results['dependency_graph']
            
            with open(output_path, 'w', encoding='utf-8') as f:
                json.dump(dependency_graph, f, indent=2, ensure_ascii=False)
            
            self.printer.print_success(f"💾 Dependency graph exported to {output_path}")
            
        except Exception as e:
            self.printer.print_error(f"Failed to export graph: {e}")
    
    async def _export_dot(self, results: Dict[str, Any], output_file: str):
        """Export dependency graph to DOT format."""
        try:
            output_path = Path(output_file)
            dependency_graph = results['dependency_graph']
            
            # Generate DOT format
            dot_content = self._generate_dot_format(dependency_graph)
            
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(dot_content)
            
            self.printer.print_success(f"💾 DOT graph exported to {output_path}")
            
        except Exception as e:
            self.printer.print_error(f"Failed to export DOT: {e}")
    
    def _generate_dot_format(self, dependency_graph: Dict[str, Any]) -> str:
        """Generate DOT format representation of dependency graph."""
        nodes = dependency_graph.get('nodes', {})
        edges = dependency_graph.get('edges', [])
        
        dot_lines = ['digraph Dependencies {']
        dot_lines.append('  rankdir=TB;')
        dot_lines.append('  node [shape=box];')
        
        # Add nodes
        for node_id, node_info in nodes.items():
            label = Path(node_id).name
            language = node_info.get('language', '')
            if language:
                label += f"\\n({language})"
            
            dot_lines.append(f'  "{node_id}" [label="{label}"];')
        
        # Add edges
        for edge in edges:
            source = edge['source']
            target = edge['target']
            dep_type = edge.get('type', '')
            
            edge_attrs = []
            if dep_type:
                edge_attrs.append(f'label="{dep_type}"')
            
            attrs_str = f' [{", ".join(edge_attrs)}]' if edge_attrs else ''
            dot_lines.append(f'  "{source}" -> "{target}"{attrs_str};')
        
        dot_lines.append('}')
        
        return '\n'.join(dot_lines)
    
    async def _export_csv(self, results: Dict[str, Any], output_file: str):
        """Export dependency list to CSV file."""
        try:
            import csv
            
            output_path = Path(output_file)
            dependency_graph = results['dependency_graph']
            edges = dependency_graph.get('edges', [])
            
            with open(output_path, 'w', newline='', encoding='utf-8') as f:
                writer = csv.writer(f)
                writer.writerow(['Source', 'Target', 'Type', 'Source Language', 'Target Language'])
                
                for edge in edges:
                    writer.writerow([
                        edge['source'],
                        edge['target'],
                        edge.get('type', ''),
                        edge.get('source_language', ''),
                        edge.get('target_language', '')
                    ])
            
            self.printer.print_success(f"💾 CSV exported to {output_path}")
            
        except Exception as e:
            self.printer.print_error(f"Failed to export CSV: {e}")
    
    async def _create_visualization(self, results: Dict[str, Any], args: argparse.Namespace):
        """Create HTML visualization of dependency graph."""
        try:
            output_path = Path(args.path) / "dependency_graph.html"
            dependency_graph = results['dependency_graph']
            
            # Generate simple HTML visualization
            html_content = self._generate_html_visualization(dependency_graph)
            
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(html_content)
            
            self.printer.print_success(f"🎨 Visualization created at {output_path}")
            
        except Exception as e:
            self.printer.print_error(f"Failed to create visualization: {e}")
    
    def _generate_html_visualization(self, dependency_graph: Dict[str, Any]) -> str:
        """Generate HTML visualization content."""
        nodes = dependency_graph.get('nodes', {})
        edges = dependency_graph.get('edges', [])
        
        # Simple HTML template with basic graph visualization
        html_template = """
<!DOCTYPE html>
<html>
<head>
    <title>CodeMCP Dependency Graph</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .node { border: 1px solid #ccc; padding: 10px; margin: 5px; background: #f9f9f9; }
        .edge { margin-left: 20px; color: #666; }
        h1 { color: #333; }
    </style>
</head>
<body>
    <h1>CodeMCP Dependency Graph</h1>
    <h2>Statistics</h2>
    <p>Nodes: {num_nodes}</p>
    <p>Edges: {num_edges}</p>
    
    <h2>Dependencies</h2>
    <div id="dependencies">
        {dependencies_html}
    </div>
</body>
</html>
        """.strip()
        
        # Generate dependencies HTML
        deps_html = ""
        for edge in edges:
            source = Path(edge['source']).name
            target = Path(edge['target']).name
            dep_type = edge.get('type', 'unknown')
            
            deps_html += f'<div class="edge">{source} → {target} ({dep_type})</div>\n'
        
        return html_template.format(
            num_nodes=len(nodes),
            num_edges=len(edges),
            dependencies_html=deps_html
        )